<template>
	<div class="upload">
	</div>
</template>

<script>
export default {
    name: 'vue-upload',
	props: {
		accept: {
			type: Object,
			default: null,
		},
		// 上传地址
		url: {
			type: String,
			default: '',
		},
		// 上传最大数量 默认为100
		fileNumLimit: {
			type: Number,
			default: 500,
		},
		// 大小限制
		fileSingleSizeLimit: {
			type: Number,
			default: 500 * 1024 * 1024,
		},
		// 所有文件大小限制
		fileSizeLimit: {
			type: Number,
			default: 10 * 1024 * 1024 * 1024,
		},
		// 上传时传给后端的参数，一般为token，key等
		formData: {
			type: Object,
			default: null
		},
		// 生成formData中文件的key，下面只是个例子，具体哪种形式和后端商议
		keyGenerator: {
			type: Function,
			default(file) {
				const currentTime = new Date().getTime()
				const key = `${currentTime}.${file.name}`
				return key
			},
		},
		multiple: {
			type: Boolean,
			default: false,
		},
		// 上传按钮ID
		uploadButton: {
				type: String,
				default: '',
		},
		headers: {
			type: Object,
			default: null
		}
	},
	data() {
		return {
			uploader: null,
			count: 0,
			flag: false,
			resetFlag: false
		}
	},
	mounted() {
		this.initWebUpload()
	},
	watch: {
		formData: function (val) {
			this.uploader.options.formData = val
		}
	},
	methods: {
		trigger( type ) {
			var args, events, allEvents;
			if ( !this._events || !type ) {
				return this;
			}
			args = slice.call( arguments, 1 );
			events = findHandlers( this._events, type );
			allEvents = findHandlers( this._events, 'all' );
			return triggerHanders( events, args ) &&
				triggerHanders( allEvents, arguments );
		},
		initWebUpload() {
			this.uploader = WebUploader.create({
				auto: false, // 选完文件后，是否自动上传
				compress: false,
				swf: '/static/lib/webuploader/Uploader.swf',  // swf文件路径
				server: this.url,  // 文件接收服务端
				pick: {
						id: this.uploadButton,     // 选择文件的按钮
						multiple: this.multiple,   // 是否多文件上传 默认false
						label: '',
				},
				// accept: this.getAccept(this.accept),  // 允许选择文件格式。
				threads: 1,
				fileNumLimit: this.fileNumLimit + 1, // 限制上传个数
				fileSizeLimit: this.fileSizeLimit, // 限制 所有文件大小
				fileSingleSizeLimit: this.fileSingleSizeLimit, // 限制单个上传文件的大小
				formData: this.formData,  // 上传所需参数
				chunked: false,          //分片上传
				// chunkSize: 2048000,    //分片大小
				duplicate: true,  // 重复上传
			})
			// 当有文件被添加进队列前调用
			this.uploader.on('beforeFileQueuedCheckfileNumLimit', (file, count) => {
				if (count > this.fileNumLimit) {
					this.$emit('error', `总文件数量须在${this.fileNumLimit}个以内`)
					return false
				} else {
					return true
				}
			})
			// 当有文件被添加进队列的时候调用
			this.uploader.on('fileQueued', (file) => {
				this.resetFlag = false
				this.$emit('fileChange', file)
			})
			// 当所有文件添加进队列完成时调用
			this.uploader.on('filesQueued', (files) => {
				// 重置判断，如果error触发，则移除队列中已添加文件
				if (this.resetFlag) {
					files.map(file => {
						this.uploader.removeFile(file)
					})
				}
			})
			this.uploader.on('uploadStart', (file) => {
				// 在这里可以准备好formData的数据
				//this.uploader.options.formData.key = this.keyGenerator(file)
				this.$emit('uploadStart', file)
			})
			this.uploader.on('uploadBeforeSend', (obj, file, headers) => {
				// 当某个文件的分块在发送前触发，主要用来询问是否要添加附带参数，大文件在开起分片上传的前提下此事件可能会触发多次。
				headers['bitaToken'] = this.headers.bitaToken
				headers['token'] = this.headers.token
				headers['userId'] = this.headers.userId
			})
			// 文件上传过程中创建进度条实时显示。
			this.uploader.on('uploadProgress', (file, percentage) => {
				this.$emit('progress', file, percentage)
			})
			this.uploader.on('uploadSuccess', (file, response) => {
				this.$emit('success', file, response)
			})
			this.uploader.on('uploadError', (file, reason) => {
				this.$emit('uploadError', file, reason)
			})
			this.uploader.on('error', (type) => {
				this.resetFlag = true
				let errorMessage = ''
				if (type === 'F_EXCEED_SIZE') {
					errorMessage = `文件大小不能超过${this.fileSingleSizeLimit / (1024 * 1024)}M`
				} else if (type === 'Q_EXCEED_NUM_LIMIT') {
					errorMessage = `总文件数量须在${this.fileNumLimit}个以内`
				} else if (type === 'Q_EXCEED_SIZE_LIMIT'){
					errorMessage = `所有文件大小不能超过${this.fileSizeLimit / (1024 * 1024)}M`
					this.uploader.reset()
				} else {
					errorMessage = `文件格式不支持上传`
				}
				this.$emit('error', errorMessage)
			})
			this.uploader.on('uploadComplete', (file, response) => {
				this.$emit('complete', file, response)
			})
			this.uploader.on('uploadFinished', () => {
				this.$emit('completeAll')
			})
		},
		upload(file) {
			this.uploader.upload(file)
		},
		stop(file) {
			this.uploader.stop(file)
		},
		reset() {
			this.uploader.reset()
		},
		getStats() {
			return this.uploader.getStats()
		},
		// 取消并中断文件上传
		cancelFile(file) {
			this.uploader.cancelFile(file)
		},
		// 在队列中移除文件
		removeFile(file, bool) {
			this.uploader.removeFile(file, bool)
		},
		getAccept(accept) {
			switch (accept) {
				case 'text':
					return {
						title: 'Texts',
						exteensions: 'doc,docx,xls,xlsx,ppt,pptx,pdf,txt',
						mimeTypes: '.doc,docx,.xls,.xlsx,.ppt,.pptx,.pdf,.txt'
					}
					break
				case 'video':
					return {
						title: 'Videos',
						exteensions: 'mp4',
						mimeTypes: '.mp4'
					}
					break
				case 'image':
					return {
						title: 'Images',
						exteensions: 'gif,jpg,jpeg,bmp,png',
						mimeTypes: '.gif,.jpg,.jpeg,.bmp,.png'
					}
					break
				default: return accept
			}
		}
	}
}
</script>

<style lang="stylus">
	.webuploader-container {
		position: relative
	}
	.webuploader-element-invisible {
		position: absolute !important
		clip: rect(1px 1px 1px 1px) /* IE6, IE7 */
		clip: rect(1px,1px,1px,1px)
	}
	.webuploader-pick {
		position: relative
		display: inline-block
		cursor: pointer
		background: #00b7ee
		padding: 10px 15px
		color: #fff
		text-align: center
		border-radius: 3px
		overflow: hidden
	}
	.webuploader-pick-hover {
		background: #00a2d4
	}
	.webuploader-pick-disable {
		opacity: 0.6
		pointer-events:none
	}
</style>
